﻿using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text.RegularExpressions;
using Ionic.Utils.Zip;

namespace ObjectShelve.Modules
{
	class UpdateProcessor
	{
		private const string VERSION_URL = "http://code.google.com/p/objectshelve/wiki/UpdateInfo";
		private const string VERSION_MASK = @"(?<=\[\$VERSION\$).+?(?=\$])";
		private const string DOWNLOAD_URL_MASK = @"(?<=\[\$URL\$).+?(?=\$])";
		private const string INFORMATION_MASK = @"(?<=\[\$INFO\$).+?(?=\$])";

		public Version OnlineVersion
		{
			get;
			private set;
		}
		public string DownloadURL
		{
			get;
			private set;
		}
		public string Information
		{
			get;
			private set;
		}

		public void GetOnlineVersionInformation()
		{			
			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(VERSION_URL);
			using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
			{
				using (StreamReader reader = new StreamReader(response.GetResponseStream()))
				{
					string html = reader.ReadToEnd();
					
					OnlineVersion = new Version(Regex.Match(html, VERSION_MASK).Value);
					DownloadURL = Regex.Match(html, DOWNLOAD_URL_MASK).Value;
					Information = Regex.Match(html, INFORMATION_MASK).Value;
				}
				response.Close();
			}

		}

		

		private string _updateFilename;
		public void Download(DownloadProgressChangedEventHandler progressHandler, System.ComponentModel.AsyncCompletedEventHandler downloadHandler)
		{
			WebClient client = new WebClient();
			if (progressHandler != null)
			{
				client.DownloadProgressChanged += progressHandler;
			}
			if (downloadHandler != null)
			{
				client.DownloadFileCompleted += downloadHandler;
			}
			client.DownloadFileCompleted += client_DownloadFileCompleted;
			string updateFilename = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
			client.DownloadFileAsync(new Uri(DownloadURL), updateFilename, updateFilename);
		}

		void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
		{
			_updateFilename = e.UserState as string;
		}

		public bool Deploy()
		{
			bool res = false;
			if (!string.IsNullOrEmpty(_updateFilename))
				using (ZipFile zip = new ZipFile(_updateFilename))
				{
					zip.ExtractAll(Environment.CurrentDirectory, true);
					File.Delete(_updateFilename);
					_updateFilename = string.Empty;
					res = true;
				}
			return res;
		}
	}
}
